using Microsoft.AspNetCore.Identity; // 引入ASP.NET Core Identity框架的核心功能
using UniversalAdmin.Domain.Entities; // 引入领域实体定义
using UniversalAdmin.Domain.Repositories; // 引入仓储接口定义
using UniversalAdmin.Application.DTOs; // 引入数据传输对象定义，用于API与服务的交互

namespace UniversalAdmin.Application.Services; // 定义服务层的命名空间

// 个人信息服务实现类，实现IPersonalService接口
public class PersonalService : IPersonalService
{
    private readonly IRepository<User> _userRepo; // 用户仓储接口实例，通过依赖注入获取
    private readonly IPasswordHasher<User> _passwordHasher; // 密码哈希服务接口实例，通过依赖注入获取

    // 构造函数，注入IRepository<User>和IPasswordHasher<User>依赖
    public PersonalService(IRepository<User> userRepo, IPasswordHasher<User> passwordHasher)
    {
        _userRepo = userRepo; // 初始化用户仓储
        _passwordHasher = passwordHasher; // 初始化密码哈希服务
    }

    // 获取当前用户信息
    public async Task<User?> GetCurrentUserAsync(Guid id)
    {
        // 调用用户仓储获取指定ID的用户信息
        return await _userRepo.GetByIdAsync(id);
    }

    // 更新用户个人资料
    public async Task UpdateProfileAsync(Guid id, UpdateProfileRequestDto dto)
    {
        // 调用用户仓储获取指定ID的用户信息
        var user = await _userRepo.GetByIdAsync(id);
        // 如果用户不存在，抛出KeyNotFoundException异常
        if (user == null) throw new KeyNotFoundException("用户不存在");

        // 更新用户信息：邮箱、电话号码、头像和个人简介
        user.Email = dto.Email;
        user.PhoneNumber = dto.PhoneNumber;
        user.Avatar = dto.Avatar;
        user.Bio = dto.Bio;
        
        // 调用用户仓储更新用户信息
        await _userRepo.UpdateAsync(user);
    }

    // 修改用户密码
    public async Task ChangePasswordAsync(Guid userId, string oldPwd, string newPwd)
    {
        // 调用用户仓储获取指定ID的用户信息
        var user = await _userRepo.GetByIdAsync(userId);
        // 如果用户不存在，抛出KeyNotFoundException异常
        if (user == null) throw new KeyNotFoundException("用户不存在");

        // 检查用户是否设置了本地密码
        if (string.IsNullOrEmpty(user.PasswordHash))
        {
            throw new InvalidOperationException("该用户账户未设置本地密码，无法执行此操作。");
        }

        // 验证旧密码是否正确
        var verify = _passwordHasher.VerifyHashedPassword(user, user.PasswordHash, oldPwd);
        if (verify == PasswordVerificationResult.Failed)
        {
            throw new UnauthorizedAccessException("旧密码错误");
        }

        // 哈希新密码并更新用户密码
        user.PasswordHash = _passwordHasher.HashPassword(user, newPwd);
        // 调用用户仓储更新用户信息
        await _userRepo.UpdateAsync(user);
    }
}